# page/list.py
"""
完整的 list 蓝图文件（可直接覆盖）
功能：
- hot_house: 热点房源（包含图片 URL 标准化）
- city_house: 城市房源（多策略匹配 + page_range）
- pattern_compat: 兼容 /list/pattern/<page>
- search_keyword: 关键字搜索
- debug_houses_by_city: 返回匹配计数与样本（JSON）
- debug_hot_images: 返回热点房源的 image 字段与文件存在情况（JSON）

注意：
- 请确保你的项目能 import 到 models.House（如 models.py 在项目根）
- 模板建议使用 house.image_url（已解析好的完整 URL）来渲染图片
"""

import os
from flask import Blueprint, render_template, current_app, request, url_for, redirect, jsonify
from sqlalchemy import or_
# 根据你项目实际路径调整导入
from models import House

list_bp = Blueprint('list', __name__, template_folder='templates')


def make_page_range(pagination, window=2):
    """
    生成要在模板中显示的页码列表，例如当前页=5, window=2 -> [3,4,5,6,7]
    """
    if not pagination:
        return []
    total_pages = getattr(pagination, 'pages', 1) or 1
    current = getattr(pagination, 'page', 1) or 1
    start = max(1, current - window)
    end = min(total_pages, current + window)
    return list(range(start, end + 1))


def resolve_image_url_for_item(img_field_value):
    """
    给定数据库里存的 image 字段值（可能是文件名或完整 URL 或 None），
    返回能直接放进 <img src="..."> 的 URL 字符串（基于 current_app.static_folder）。
    解析优先级：
      1) 如果以 http/https 开头，直接返回该 URL
      2) 如果文件存在于 static/uploads/<name> -> 返回 url_for('static', filename='uploads/<name>')
      3) 如果文件存在于 static/images/<name>  -> 返回 url_for('static', filename='images/<name>')
      4) 回退到 static/uploads/default_house.jpg 或 static/images/default_house.jpg 或 static/img/house-bg1.jpg
    """
    static_root = current_app.static_folder  # usually <project>/static
    default_candidates = [
        ('uploads', 'default_house.jpg'),
        ('images', 'default_house.jpg'),
        ('img', 'house-bg1.jpg'),
    ]

    # 1) full URL
    try:
        if img_field_value and isinstance(img_field_value, str) and img_field_value.strip().lower().startswith(('http://', 'https://')):
            return img_field_value.strip()
    except Exception:
        pass

    # 2) treat as filename - check uploads then images
    if img_field_value and isinstance(img_field_value, str):
        name = img_field_value.strip()
        # avoid path traversal - take basename
        name = os.path.basename(name)
        uploads_path = os.path.join(static_root, 'uploads', name)
        images_path = os.path.join(static_root, 'images', name)
        if os.path.exists(uploads_path):
            return url_for('static', filename=f'uploads/{name}')
        if os.path.exists(images_path):
            return url_for('static', filename=f'images/{name}')

    # 3) fallback defaults
    for folder, fname in default_candidates:
        path = os.path.join(static_root, folder, fname)
        if os.path.exists(path):
            return url_for('static', filename=f'{folder}/{fname}')

    # final fallback (should exist in your repo)
    return url_for('static', filename='img/house-bg1.jpg')


@list_bp.route('/hot_house/<int:page>')
def hot_house(page=1):
    """
    热点房源分页列表（模板建议使用 house.image_url）
    """
    per_page = current_app.config.get('HOT_PER_PAGE', 12)

    # 选择排序列（优先热度或浏览量）
    if hasattr(House, 'heat'):
        order_col = getattr(House, 'heat').desc()
    elif hasattr(House, 'page_views'):
        order_col = getattr(House, 'page_views').desc()
    else:
        order_col = getattr(House, 'id').desc()

    pagination = House.query.order_by(order_col).paginate(page=page, per_page=per_page, error_out=False)
    houses = pagination.items if pagination else []

    # 标准化每条记录的 image_url
    for h in houses:
        img_val = getattr(h, 'image', None)
        try:
            h.image_url = resolve_image_url_for_item(img_val)
        except Exception:
            # 兜底：确保模板至少能显示一个存在的图片
            h.image_url = url_for('static', filename='img/house-bg1.jpg')

    page_range = make_page_range(pagination, window=2) if pagination else []

    # 打印部分调试信息，开发时可查看控制台
    try:
        print(f"DEBUG hot_house: page={page}, per_page={per_page}, returned={len(houses)} items")
    except Exception:
        pass

    return render_template('hot_list.html', houses=houses, pagination=pagination, page_range=page_range)


@list_bp.route('/city/<city>/<int:page>')
def city_house(city, page=1):
    """
    城市房源列表（多策略匹配 + image_url 标准化）
    匹配策略（按顺序）：
      - House.region LIKE '%city%'
      - House.city == city
      - House.address LIKE '%city%'
      - House.community LIKE '%city%'
    """
    per_page = current_app.config.get('CITY_PER_PAGE', 12)
    pagination = None
    tried = []

    # 1) region 模糊
    try:
        if hasattr(House, 'region'):
            q1 = House.query.filter(getattr(House, 'region').like(f"%{city}%"))
            cnt1 = q1.count()
            tried.append(("region.like", cnt1))
            if cnt1 > 0:
                pagination = q1.paginate(page=page, per_page=per_page, error_out=False)
    except Exception as e:
        tried.append(("region.like_error", str(e)))

    # 2) city 精确
    if not pagination or (hasattr(pagination, 'total') and pagination.total == 0):
        try:
            if hasattr(House, 'city'):
                q2 = House.query.filter(getattr(House, 'city') == city)
                cnt2 = q2.count()
                tried.append(("city.eq", cnt2))
                if cnt2 > 0:
                    pagination = q2.paginate(page=page, per_page=per_page, error_out=False)
        except Exception as e:
            tried.append(("city.eq_error", str(e)))

    # 3) address 模糊
    if not pagination or (hasattr(pagination, 'total') and pagination.total == 0):
        try:
            if hasattr(House, 'address'):
                q3 = House.query.filter(getattr(House, 'address').like(f"%{city}%"))
                cnt3 = q3.count()
                tried.append(("address.like", cnt3))
                if cnt3 > 0:
                    pagination = q3.paginate(page=page, per_page=per_page, error_out=False)
        except Exception as e:
            tried.append(("address.like_error", str(e)))

    # 4) community 模糊
    if not pagination or (hasattr(pagination, 'total') and pagination.total == 0):
        try:
            if hasattr(House, 'community'):
                q4 = House.query.filter(getattr(House, 'community').like(f"%{city}%"))
                cnt4 = q4.count()
                tried.append(("community.like", cnt4))
                if cnt4 > 0:
                    pagination = q4.paginate(page=page, per_page=per_page, error_out=False)
        except Exception as e:
            tried.append(("community.like_error", str(e)))

    # 回退到全表分页（仅供调试/查看）
    if not pagination:
        try:
            all_q = House.query
            cnt_all = all_q.count()
            tried.append(("all.count", cnt_all))
            pagination = all_q.paginate(page=page, per_page=per_page, error_out=False)
        except Exception as e:
            tried.append(("all_error", str(e)))
            pagination = None

    # 打印 debug 信息
    try:
        print("DEBUG city_house tried strategies:", tried)
    except Exception:
        pass

    houses = pagination.items if pagination else []
    # 解析 image_url
    for h in houses:
        try:
            h.image_url = resolve_image_url_for_item(getattr(h, 'image', None))
        except Exception:
            h.image_url = url_for('static', filename='img/house-bg1.jpg')

    page_range = make_page_range(pagination, window=2) if pagination else []
    return render_template('city_list.html', houses=houses, pagination=pagination, city=city, page_range=page_range)


@list_bp.route('/pattern/<int:page>')
def pattern_compat(page=1):
    """
    兼容旧链接 /list/pattern/<page> -> 跳转到 /list/city/北京/<page>
    """
    return redirect(url_for('list.city_house', city='北京', page=page))


@list_bp.route('/search/<keyword>/<int:page>')
def search_keyword(keyword, page=1):
    """
    简单关键字检索（按 address / community 模糊匹配），并标准化 image_url
    """
    per_page = current_app.config.get('SEARCH_PER_PAGE', 12)
    pagination = None
    tried = []
    try:
        filters = []
        if hasattr(House, 'address'):
            filters.append(getattr(House, 'address').like(f"%{keyword}%"))
        if hasattr(House, 'community'):
            filters.append(getattr(House, 'community').like(f"%{keyword}%"))
        if filters:
            q = House.query.filter(or_(*filters))
            cnt = q.count()
            tried.append(("address/community.like", cnt))
            if cnt > 0:
                pagination = q.paginate(page=page, per_page=per_page, error_out=False)
    except Exception as e:
        tried.append(("address/community_error", str(e)))

    if not pagination:
        try:
            all_q = House.query
            cnt_all = all_q.count()
            tried.append(("all.count", cnt_all))
            pagination = all_q.paginate(page=page, per_page=per_page, error_out=False)
        except Exception as e:
            tried.append(("all_error", str(e)))
            pagination = None

    try:
        print("DEBUG search_keyword tried strategies:", tried)
    except Exception:
        pass

    houses = pagination.items if pagination else []
    for h in houses:
        try:
            h.image_url = resolve_image_url_for_item(getattr(h, 'image', None))
        except Exception:
            h.image_url = url_for('static', filename='img/house-bg1.jpg')

    page_range = make_page_range(pagination, window=2) if pagination else []
    return render_template('search_list.html', houses=houses, pagination=pagination, keyword=keyword, page_range=page_range)


@list_bp.route('/debug/houses_by_city/<city>')
def debug_houses_by_city(city):
    """
    Debug 路由：检查 DB 中各种匹配情况及样本数据
    访问: /list/debug/houses_by_city/北京
    """
    result = {}
    try:
        result['region_like_count'] = House.query.filter(getattr(House, 'region').like(f"%{city}%")).count() if hasattr(House, 'region') else 'no_field'
    except Exception as e:
        result['region_like_error'] = str(e)

    try:
        result['city_eq_count'] = House.query.filter(getattr(House, 'city') == city).count() if hasattr(House, 'city') else 'no_field'
    except Exception as e:
        result['city_eq_error'] = str(e)

    try:
        result['address_like_count'] = House.query.filter(getattr(House, 'address').like(f"%{city}%")).count() if hasattr(House, 'address') else 'no_field'
    except Exception as e:
        result['address_like_error'] = str(e)

    try:
        result['community_like_count'] = House.query.filter(getattr(House, 'community').like(f"%{city}%")).count() if hasattr(House, 'community') else 'no_field'
    except Exception as e:
        result['community_like_error'] = str(e)

    # sample rows
    try:
        samples = House.query.limit(5).all()
        def s2d(h):
            return {
                'id': getattr(h, 'id', None),
                'region': getattr(h, 'region', None),
                'city': getattr(h, 'city', None),
                'address': getattr(h, 'address', None),
                'community': getattr(h, 'community', None),
                'image': getattr(h, 'image', None),
                'price': getattr(h, 'price', None),
            }
        result['sample'] = [s2d(h) for h in samples]
    except Exception as e:
        result['sample_error'] = str(e)

    return jsonify(result)


@list_bp.route('/debug/hot_images')
def debug_hot_images():
    """
    Debug 路由：列出热点房源的 image 字段与磁盘上是否存在对应文件（JSON）。
    访问: /list/debug/hot_images
    """
    out = []
    try:
        # 取前 20 条热点（按 page_views 或 id）
        if hasattr(House, 'page_views'):
            q = House.query.order_by(getattr(House, 'page_views').desc())
        else:
            q = House.query.order_by(getattr(House, 'id').desc())
        items = q.limit(20).all()
        static_root = current_app.static_folder
        for h in items:
            img = getattr(h, 'image', None)
            exists_uploads = False
            exists_images = False
            if img and isinstance(img, str):
                name = os.path.basename(img.strip())
                exists_uploads = os.path.exists(os.path.join(static_root, 'uploads', name))
                exists_images = os.path.exists(os.path.join(static_root, 'images', name))
            out.append({
                'id': getattr(h, 'id', None),
                'image_field': img,
                'exists_uploads': exists_uploads,
                'exists_images': exists_images,
                'image_url_resolved': resolve_image_url_for_item(img)
            })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

    return jsonify(out)
